/**
 * Copyright (c) 2009 Moogene
 * All rights reserved
 *
 * This software is the confidential and proprietary information of Moogene.
 * You shall not disclose such Confidential Information and shall use it only
 * in accordance with the terms of the license agreement you entered into
 * with Moogene
 */

package com.moogene.android.engine.mmi;

import com.moogene.android.engine.action.ActTouchEvent;
import com.moogene.android.engine.action.ActionListener;
import com.moogene.android.engine.action.ActionManager;
import com.moogene.android.engine.action.ActionMonitor;

import android.graphics.Canvas;
import android.util.Log;

import java.lang.ref.SoftReference;
import java.util.ArrayList;
import java.util.HashMap;

/**
 * @author Song, jiawei
 *
 */
public class Book implements ActionListener {
	final private static String TAG = "Book";
	public static long sBookCounter;

	public static long sCurPageCounter;

	private static Book sBook;

	private static Page sCurPage;

	private static ArrayList<FTimerTask> sFTimerTasks;
	
	private final HashMap<String, SoftReference<Page>> softCachePages;

	private Book() {
		sBookCounter = 0;
		sFTimerTasks = new ArrayList<FTimerTask>();
		softCachePages = new HashMap<String, SoftReference<Page>>();
	}

	public static Book getInstance() {
		if (sBook == null) {
			sBook = new Book();
		}
		return sBook;
	}

	public ActionMonitor getActionMonitor(){
		return ActionManager.getInstance().getActionMonitor();
	}

	public Page getCurrentPage() {
		return sCurPage;
	}

	public long getBookCounter() {
		return sBookCounter;
	}

	public long getCurPageCounter() {
		return sCurPageCounter;
	}

	public void setTransition(Transition transition) {

	}

	private void gotoPage(Page page) {
//		if (!page.isResReady()) {
//			page.loadRes();
//		}
		page.onStart();
		sCurPage = page;
		sCurPageCounter = 0;
	}
	
	public void gotoPage(String name, boolean noCache) {
		if(noCache){
			try {
				Page p = (Page)Class.forName(com.moogene.android.Config.UI_OBJECT_CLASS_ROOT_PATH + name).newInstance();
				p.onInit();
				gotoPage(p);
			} catch (InstantiationException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			} catch (ClassNotFoundException e) {
				throw new IllegalArgumentException("No Class found under " + com.moogene.android.Config.UI_OBJECT_CLASS_ROOT_PATH + name);
			}
		}else{
			gotoPage(name);
		}
	}
	
//	public void gotoPage(String name){
//		gotoPage(name, null);
//	}
//	
	public void gotoPage(String name, String... args) {
		Page p = null;
		if (softCachePages.get(name) != null) {
			p = softCachePages.get(name).get();
		}
		if (p == null) {
			try {
				p = (Page)Class.forName(com.moogene.android.Config.UI_OBJECT_CLASS_ROOT_PATH + name).newInstance();
				p.onInit(args);
			} catch (InstantiationException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			} catch (ClassNotFoundException e) {
				throw new IllegalArgumentException("No Class found under " + com.moogene.android.Config.UI_OBJECT_CLASS_ROOT_PATH + name);
			}
		}
		softCachePages.put(name, new SoftReference<Page>(p));
		gotoPage(p);
	}

	public void addLayer(Layer layer) {
		sCurPage.addLayer(layer);
	}

	public void removeLayer(Layer layer) {
		sCurPage.removeLayer(layer);
		layer = null;
	}

	public void update() {
	    sCurPageCounter++;
	    sBookCounter++;
	    log("sBookCounter = " + sBookCounter);
		sCurPage.update();
		updateTimerTask();
	}

	public void draw(Canvas canvas) {
		sCurPage.draw(canvas);
	}

	@Override
	public boolean actionPerformed(ActTouchEvent actionEvent) {
		return sCurPage.actionPerformed(actionEvent);
	}

	public void schedule(FTimerTask ftt){
	    sFTimerTasks.add(ftt);
	}
	
	public void cancel(FTimerTask ftt){
		sFTimerTasks.remove(ftt);
	}

	private void updateTimerTask() {
		@SuppressWarnings("unchecked")
		ArrayList<FTimerTask> ttasks = (ArrayList<FTimerTask>) sFTimerTasks.clone();
		for (FTimerTask ftt : ttasks) {
			if (ftt.update()) {
				sFTimerTasks.remove(ftt);
			}
		}
	}
    static void log(String msg) {
        if (Config.LOG_ENABLE) {
            Log.d(Config.LOG_TAG + "-"
                    + TAG, msg);
        }
    }
}
